package com.gl.framework.security.service;

import java.util.TimerTask;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;

import com.gl.common.constant.Constants;
import com.gl.common.constant.RedisConstants;
import com.gl.common.exception.CustomException;
import com.gl.common.exception.user.CaptchaException;
import com.gl.common.exception.user.CaptchaExpireException;
import com.gl.common.exception.user.UserPasswordNotMatchException;
import com.gl.common.util.i18n.MessageUtils;
import com.gl.common.util.redis.RedisUtils;
import com.gl.framework.manager.AsyncManager;
import com.gl.framework.manager.factory.AsyncFactory;
import com.gl.framework.security.LoginUser;

/**
 * 登录校验方法
 */
@Component
public class SysLoginService {

	@Autowired
	private TokenService tokenService;

	@Resource
	private AuthenticationManager authenticationManager;

	@Autowired
	private RedisUtils redisUtils;

	/**
	 * 登录验证
	 *
	 * @param loginName 登录账号
	 * @param password  密码
	 * @param code   验证码
	 * @param uuid      唯一标识
	 * @return token
	 */
	public String login(String loginName, String password, String code, String uuid) {
		String verifyKey = RedisConstants.CAPTCHA_CODE_KEY + uuid;
		Object captcha = redisUtils.get(verifyKey);
		redisUtils.del(verifyKey);
		if (captcha == null) {
			AsyncManager.me().execute(AsyncFactory.recordLoginLog(loginName, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire")));
//			throw new CaptchaExpireException();
			throw new CustomException("验证码已过期");
		}
		if (!code.equalsIgnoreCase(captcha.toString())) {
			AsyncManager.me().execute(AsyncFactory.recordLoginLog(loginName, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error")));
			//throw new CaptchaException();
			throw new CustomException("验证码错误");
		}

		// 用户验证
		Authentication authentication = null;
		try {
			// 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
			authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(loginName, password));
		} catch (Exception e) {
			if (e instanceof BadCredentialsException) {
				AsyncManager.me().execute(AsyncFactory.recordLoginLog(loginName, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
				//throw new UserPasswordNotMatchException();
				throw new CustomException("账户或密码错误");
			} else {
				AsyncManager.me().execute(AsyncFactory.recordLoginLog(loginName, Constants.LOGIN_FAIL, e.getMessage()));
				//throw new CustomException(e.getMessage());
				//throw new UserPasswordNotMatchException();
				throw new CustomException("账户或密码错误");
			}
		}
		TimerTask timerTask = AsyncFactory.recordLoginLog(loginName, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"));

		AsyncManager.me().execute(timerTask);
		LoginUser loginUser = (LoginUser) authentication.getPrincipal();

		// 生成token
		return tokenService.createToken(loginUser);
	}
}
